<!DOCTYPE html>
<html>
    <head>
        <!-- Update title -->
        <title>Flocking: Part 1</title>

        <!-- keywords used for searching -->
        <meta name="keywords" content="guide, flocking, particles">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <!-- reference to Cinder classes -->
        <!-- <ci seealso dox="[CLASS NAME GOES HERE]" label="[NAME OF LINK]"></ci> -->

        <!-- master stylesheet - these links will be replaced when compiled -->
        <link rel="stylesheet" href="../../_assets/css/foundation.css">
        <link rel="stylesheet" href="../../_assets/css/prism.css">
        <link rel="stylesheet" href="../../_assets/css/style.css">
        <link href='http://fonts.googleapis.com/css?family=Open+Sans:400,300,600,700' rel='stylesheet' type='text/css'>

        <!-- Place additional stylsheet links here, which will be copied over when compiled (optional) -->
        
    </head>

    <body id="guide-contents" class="language-c++">

        <!-- CONTENT STARTS HERE -->
        <h1><a class="anchor" id="alignment"></a>
        RULE 3: ALIGNMENT</h1>
        <p><br />
        </p><div class="image">
        <img src="images/rule3.jpg" alt="rule3.jpg"/>
        </div>
        <p> <br />
         <br />
        It is time to introduce the third rule. As you recall, the first rule was an act of separation. If an object gets too crowded, it tries to move away from its neighbors. The second rule is an act of cohesion. If an object moves too far away, it tries to move towards its neighbors. These two rules alone are enough to make some interesting flocking simulations. The resulting look is not too dissimilar from how tiny winged insects behave: a seemingly chaotic wandering but still exhibiting some group behavior. <br />
         <br />
        Rule 3 gets us to a more familiar and less random looking system. This rule says that if a neighbor is not too far away or too close, then emulate its velocity. Or in other words, move like your neighbors move. <br />
         <br />
        Let's bring back the <em>applyForce()</em> method to see what changes were made to accommodate this new third zone. <br />
         <br />
         
        <div class="fragment"><pre class="fragment"><span style="font-size: x-small; line-height: 1px;">void ParticleController::applyForce( float zoneRadiusSqrd, float lowThresh, float highThresh  )
        {
            for( list::iterator p1 = mParticles.begin(); p1 != mParticles.end(); ++p1 ) {
                list::iterator p2 = p1;
                for( ++p2; p2 != mParticles.end(); ++p2 ) {
                    Vec3f dir = p1-&gt;mPos - p2-&gt;mPos;
                    float distSqrd = dir.lengthSquared();

                    if( distSqrd &lt; zoneRadiusSqrd ) { <span style="color: #888888;">// If the neighbor is within the zone radius...</span>
                        float percent = distSqrd/zoneRadiusSqrd;

                        if( percent &lt; lowThresh ) { <span style="color: #888888;">// ... and is within the lower threshold limits, separate...</span>
                            <span style="color: #3366ff;">float F = ( lowThresh/percent - 1.0f ) * 0.01f;
                            dir = dir.normalize() * F;
                            p1-&gt;mAcc += dir;
                            p2-&gt;mAcc -= dir;</span>
                        }
                        else if( percent &lt; highThresh ) { <span style="color: #888888;">// ... else if it is within the higher threshold limits, align...</span>
                            <span style="color: #008000;">float threshDelta = highThresh - lowThresh;
                            float adjustedPercent = ( percent - lowThresh )/threshDelta;
                            float F = ( 0.5f - cos( adjustedPercent * M_PI * 2.0f ) * 0.5f + 0.5f ) * 0.01f;
                            p1-&gt;mAcc += p2-&gt;mVel.normalized() * F;
                            p2-&gt;mAcc += p1-&gt;mVel.normalized() * F;</span>
                        }
                        else { <span style="color: #888888;">// ... else, attract.</span>
                            <span style="color: #ff0000;">float threshDelta = 1.0f - highThresh;
                            float adjustedPercent = ( percent - highThresh )/threshDelta;
                            float F = ( 0.5f - cos( adjustedPercent * M_PI * 2.0f ) * 0.5f + 0.5f ) * 0.01f;
                            dir = dir.normalize() * F;
                            p1-&gt;mAcc -= dir;
                            p2-&gt;mAcc += dir;</span>
                        }
                    }
                }
            }
        }</span></pre></div>
        </p>
        <p><br />
        The orientation force is similar to what we are doing with the cohesive force. We normalize the Particle's position within the range which it finds itself, and then use that normalized position to find the position along the inverted cosine. Here is what our curve now looks like. <br />
         <br />
        </p><div class="image">
        <img src="images/curve3.jpg" alt="curve3.jpg"/>
        </div>
        <p> <br />
         <br />
        There is another difference with the alignment force that is different from separation and cohesion forces. The alignment force doesn't care about the vector between the interacting particles. It is more interested in the other particle's current velocity. This is why we are referencing <em>mVel</em> of the other Particle instead of manipulating the <em>dir</em> vector between Particles. If you are not too close to me and not too far away from me, I want to start moving in the direction you are moving. This simple process is what helps to create group flocking behavior in a random collection of particles with random starting positions and random starting velocities. <br />
         <br />
        When you run the Chapter 4 Flocking app, you will get a random mess of particles but after a couple seconds, groups will begin to form. <br />
         <br />
        </p><div class="image">
        <img src="images/chapter4b.jpg" alt="chapter4b.jpg"/>
        </div>
        <p> <br />
         <br />
        It is not uncommon for the flocking Particles to begin to form vortices that are characteristic of many species of fish. In the image below, thousands of sardines swim into a tight formation known as a <a href="http://en.wikipedia.org/wiki/Shoaling_and_schooling">bait ball</a> which is a type of shoaling. <br />
         <br />
        </p><div class="image">
        <img src="images/3706256557_a98ab377d1_b.jpg" alt="3706256557_a98ab377d1_b.jpg"/>
        </div>
        <p><em>Photo credit: Erwin Poliakoff (Flickr:epddiver)</em> <br />
        <br />
        </p><div class="image">
        <img src="images/chapter4a.jpg" alt="chapter4a.jpg"/>
        </div>
        <p> <br />
         <br />
        There you have it. A fairly basic 3D flocking particle simulation. In <a class="el" href="chapter5.html">Flocking Chapter 5</a>, we are going to show different ways you can improve the behavior of the flocking and also add in a few predators.</p>
        <p><br />
        </p>
        
        <!-- END CONTENT -->

        <!-- Scripts -->
        <script src="../../_assets/js/prism.js" type="text/javascript"></script>
        <!-- Place additional scripts here (optional) -->
        <!-- <script type="text/javascript"></script> -->

    </body>
</html> 